package com.cloudlead.utils.lang;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;

/**
 * 执行本地的操作系统命令
 * 
 * @author dean.lu
 * 
 */
public class ExecuteLocalCommandUtils {

	public static void execute(String command, String[] envp, File dir,
			List<String> errors, List<String> outputs) throws IOException,
			InterruptedException {
		final Runtime runtime = Runtime.getRuntime();
		String[] commands;

		// 根据操作系统的不同执行不同的命令
		String os = SystemPropertyUtils.getOSName();
		if (os.startsWith("Windows")) {
			commands = new String[] { "cmd", "/C", command };
		} else if (os.startsWith("Linux")) {
			commands = new String[] { "/bin/bash", "-c", command };
		} else {
			throw new IllegalArgumentException(
					"Not supported operation system.");
		}

		final Process process = runtime.exec(commands, envp, dir);

		ProcessResult processResult = execProcess(process);
		System.out.println(processResult);

		if (null != processResult) {
			if (errors != null) {
				errors.addAll(processResult.errors);
			}
			if (outputs != null) {
				outputs.addAll(processResult.outputs);
			}
		}
	}

	private static ProcessResult execProcess(final Process process)
			throws IOException, InterruptedException {
		List<String> errors = new ArrayList<>();
		List<String> outputs = new ArrayList<>();

		// 获取系统默认的字符集
		String charsetName = SystemPropertyUtils.getSystemChartset();

		// 读取命令执行过程中的异常
		BufferedReader errorReader = null;
		try {
			errorReader = new BufferedReader(new InputStreamReader(
					process.getErrorStream(), charsetName));
			String errorLine;
			while ((errorLine = errorReader.readLine()) != null) {
				errors.add(errorLine);
			}
		} finally {
			if (null != errorReader) {
				errorReader.close();
			}
		}

		// 读取命令执行的结果
		BufferedReader reader = null;
		try {
			reader = new BufferedReader(new InputStreamReader(
					process.getInputStream(), charsetName));
			String line;
			while ((line = reader.readLine()) != null) {
				outputs.add(line);
			}
		} finally {
			if (null != reader) {
				reader.close();
			}
		}
		process.waitFor();
		ProcessResult result = new ProcessResult();
		result.errors = errors;
		result.outputs = outputs;
		return result;
	}

	static class ProcessResult {
		private List<String> errors;
		private List<String> outputs;

		@Override
		public String toString() {
			return "ProcessResult {errors:" + errors + ", outputs:" + outputs
					+ "}";
		}

	}

	public static void main(String[] args) throws IOException,
			InterruptedException, ExecutionException, TimeoutException {
		execute("dir", null, new File("d:/"), null, null);
	}
}
